#ifndef __THREAD_POOL__
#define __THREAD_POOL__
#include <func.h>
#include "taskQueue.h"
#include <openssl/md5.h>

#define MD5_SIZE 16
#define MD5_STR_LEN (MD5_SIZE * 2)
#define CLIENT_NUM 50 // 客户端表大小

// 用于存储已连接客户端的user_id，数组下标为其netfd
extern int client_id[CLIENT_NUM];

typedef struct threadPool_s
{
    pthread_t *tidArr;
    int threadNum;
    taskQueue_t taskQueue;
    int isexit;
} threadPool_t;

enum e_command
{
    CMD_CD,     // 进入对应目录
    CMD_LS,     // 列出相应目录文件
    CMD_PUTS,   // 上传本地文件至服务器
    CMD_GETS,   // 从服务器下载文件到本地
    CMD_REMOVE, // 删除服务器上的文件
    CMD_PWD,    // 显示当前所在路径
    CMD_MKDIR,  // 创建文件夹
    CMD_LOGIN,  // 用户登录
    CMD_SIGNUP  // 用户注册
};

int threadPoolInit(threadPool_t *pthreadPool, int workerNum);
int makeWorker(threadPool_t *pthreadPool);
void *threadFunc(void *pargs);
int tcpInit(char *config_file, int *psockfd);
int epollCtor();
int epollAdd(int epfd, int fd);
int epollDel(int epfd, int fd);
int transFile(int netfd, cmd_t Cmd);
int recvn(int netfd, void *buf, int length);
int recvFile(int netfd, int user_id);
int cmd_cd(int netfd, cmd_t Cmd);
int cmd_ls(int netfd, cmd_t Cmd);
int cmd_pwd(int netfd, cmd_t Cmd);
int cmd_mkdir(int netfd, cmd_t Cmd);
int cmd_remove(int netfd, cmd_t Cmd);
int cmd_gets(int netfd, cmd_t Cmd);
int cmd_puts(int netfd, cmd_t Cmd);
// 用户登录相关函数
int user_login(int netfd, cmd_t Cmd);
int user_signup(int netfd, cmd_t Cmd);
void get_salt(char *salt);
// 计算md5值
int Compute_file_md5(char *file_path, char *md5_str);
// mysql相关函数
int mysqlconnect(MYSQL **mysql);
int do_query(char *query, MYSQL **mysql);
int get_user_code(int user_id, int *pcode);
int get_user_pwd(int user_id, char *pwd);
int get_parent_id(int id, int *pparent_code);
int update_user_path(int user_id, char *pwd, int code);
int get_file_code(int user_id, char *filename, int *pcode, int parent_id, char *type);
int init_local_file();
int remove_local_file();
int get_fsystem_md5(char *file, int user_id, int parent_id, char *md5_str);
int add_fsystem_file(int parent_id, char *filename, int owner_id, char *md5_str, off_t filesize);
int if_local_exist(char *md5_str);
int get_real_file_name(char *md5_str, char *real_file_name);
int add_link(char *md5_str);
int minus_file_link(char *md5_str);
int minus_dir_link(MYSQL **mysql, int user_id, int dir_id);
int add_local_file(char *md5_str, char *real_name);
int find_code_files(int netFd, int code, int user_id);
int add_fsystem_dir(int parent_id, char *dirname, int owner_id);
int del_fsystem_file(int code, int user_id);

typedef struct train_s
{
    int length;
    char data[1000];
} train_t;
#define SYS_LOG_INFO(Cmd){char *p;switch (Cmd.token){case CMD_CD:p = "cd";break;case CMD_LS:p = "ls";break;case CMD_PUTS:p = "puts";break;case CMD_GETS:p = "gets";break;case CMD_REMOVE:p = "remove";break;case CMD_PWD:p = "pwd";break;case CMD_LOGIN:p = "user log in";break;case CMD_SIGNUP:p = "user sign up";break;default:p = "exit";}time_t now = time(NULL);struct tm *pTm = localtime(&now);syslog(LOG_INFO, "%d/%d/%d %02d:%02d:%02d user: %s %s", pTm->tm_year + 1900, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec, p, Cmd.object);}
#define LOG_ERROR(ret,retval,func_name) {if(ret==retval) {time_t now = time(NULL); struct tm *pTm = localtime(&now);printf("%d/%d/%d %02d:%02d:%02d %s:%s",pTm->tm_year + 1900,pTm->tm_mon + 1,pTm->tm_mday,pTm->tm_hour,pTm->tm_min,pTm->tm_sec,func_name,strerror(errno));}}
#endif